<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>继承</title>
</head>

<body>
    <!-- 
       1. 原型链继承
            1. 套路
                1. 定义父类型构造函数
                2. 给父类型的原型添加方法
                3. 定义子类型的构造函数
                4. 创建父类型的对象赋值给子类型的原型
                5. 将子类型原型的构造属性设置为子类型
                6. 给子类型原型添加方法
                7. 创建子类型的对象： 可以调用父类型的方法
            2. 关键
                子类型的原型为父类型的一个实例对象
            3. 注意
                要将原型的构造方法设置为子类型
        2. 借用构造函数继承
            1. 套路：
                1. 定义父类型构造函数
                2. 定义子类型构造函数
                3. 在子类型构造函数中调用父类型构造函数
            2. 关键：
                在子类型构造函数中通过call()调用父类型构造函数
        3. 原型链+借用构造函数的组合继承
            1. 利用原型链实现对父类型对象的方法继承
            2. 利用call()借用父类型构造函数初始化相同属性
    -->
    <script>
        // 原型链继承
        function Supper() {
            this.supProp = 'Supper property'
        }
        Supper.prototype.showSupperProp = function () {
            console.log(this.supProp)
        }

        function Sub() {
            this.subProp = 'Sub Property'
        }
        // 将原型指向父类
        Sub.prototype = new Supper()
        // 将原型的构造方法指向子类型
        Sub.prototype.constructor = Sub
        Sub.prototype.showSubProp = function () {
            console.log(this.subProp)
        }

        var sub = new Sub()
        sub.showSubProp()
        sub.showSupperProp()
        console.log(Sub.constructor)


        // 通过构造函数继承
        function Person2(name, age) {
            this.name = name
            this.age = age
        }
        function Student(name, age, price) {
            // 相当于this.Person2(name, age) ==> this.name = name;this.age = age
            // 但是不能这样用
            Person2.call(this, name, age)
            this.price = price
        }
        var s = new Student('Beauty', 21, 14000)
        console.log(s.name, s.age, s.price)


        // 组合继承
        function Person3(name, age) {
            this.name = name
            this.age = age
        }
        Person3.prototype.setName = function (name) {
            this.name = name
        }
        function Student2(name, age, price) {
            // 相当于this.Person2(name, age) ==> this.name = name;this.age = age
            // 但是不能这样用
            Person3.call(this, name, age)
            this.price = price
        }
        Student2.prototype = new Person3()
        Student2.prototype.constructor = Student2
        var s2 = new Student2('Beauty', 21, 16000)
        s2.setName('Little Beauty')
        console.log(s2.name, s2.age, s2.price)
    </script>
</body>

</html>